#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <stdlib.h>
#include <stdio.h>

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <wait.h>

GLfloat roadWidth = 200.0;
GLfloat roadLength = 23000.0;

GLfloat markingWidth = 5.0;
GLfloat markingLength = 10.0;
GLfloat markingSpace = 20.0;

GLfloat camHeight = 75.0;
GLfloat footLong = 50.0;
GLint upto = 300; // limit on extent of coordinate axes

GLfloat speedParam = 0.3;

GLfloat camera_x=0.0, camera_y=0.0, camera_z=0.0;

void init(void)
{
	glClearColor (0.0, 0.0, 0.0, 0.0);
	glShadeModel (GL_FLAT);
	camera_x = roadWidth/2, camera_y = camHeight, camera_z=0.0;
}

void renderMarkings(void)
{
	glColor3f(128.0, 0.0, 0.0);
	GLfloat x=roadWidth/2-markingWidth/2, m=markingWidth, n=markingLength, y=0.0, p=markingSpace;
	int t=0, mc=roadLength/(markingLength+markingSpace);
	glBegin(GL_QUADS);
		for(t=0; t<mc;t++){
			glVertex3f(x, y, t*(n+p));
			glVertex3f(x+m, y, t*(n+p));
			glVertex3f(x+m, y, t*(n+p)+n);
			glVertex3f(x, y, t*(n+p)+n);
		}
	glEnd();
}

void renderRoad(void)
{
	printf("Rendering road...\n");
	glColor3f(0.0, 0.0, 255);
	glBegin(GL_POLYGON);
		glVertex3f(0.0, 0.0, 0.0);
		glVertex3f(roadWidth, 0.0, 0.0);
		glVertex3f(roadWidth, 0.0, roadLength);
		glVertex3f(0.0, 0.0, roadLength);
	glEnd();
}

void renderAxes(void)
{
	printf("Rendering Axes...\n");
	glBegin(GL_LINES);
		glColor3f(255.0, 0.0, 0.0); // x-axis
		glVertex3i(0, 0, 0);
		glVertex3i(upto, 0, 0);

		glColor3f(0.0, 255.0, 0.0); // y-axis
		glVertex3i(0, 0, 0);
		glVertex3i(0, 255, 0);

		glColor3f(0.0, 0.0, 255.0);  // z-axis
		glVertex3i(0, 0, 0);
		glVertex3i(0, 0, upto);
	glEnd();
}

void display(void)
{
	glClear (GL_COLOR_BUFFER_BIT);
	renderAxes();
	renderRoad();
	renderMarkings();
	glFlush ();
	glutSwapBuffers();
}

void idle()
{
	camera_z += speedParam;
	printf("camera ka zed component %f\n", camera_z);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(camera_x, camera_y, camera_z,
			camera_x, 0.0, camera_z+footLong,
			0.0, 2.0, 3.0);

	glutPostRedisplay();
}

void reshape (int w, int h)
{
	glViewport (0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode (GL_PROJECTION); // set mode to projection
	glLoadIdentity (); // Load identity matrix
	glFrustum (-50, 50, -50, 50, 40.0, 300);  // specify clipping volume
	glMatrixMode (GL_MODELVIEW); // set mode back to modelview
	glLoadIdentity (); // clear current matrix
	gluLookAt(camera_x, camera_y, camera_z,
			camera_x, 0.0, camera_z+footLong,
			0.0, 2.0, 3.0);
}

void keyboard(unsigned char key, int x, int y)
{
	switch(key){
	case 's': // move left
		if(camera_x<roadWidth)
			camera_x += 1;
		break;
	case 'd': // move right
		if(camera_x>0)
			camera_x -= 1;
		break;
	default:
		printf("Key pressed is %c\n", key);
	}
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize (700, 700);
	glutInitWindowPosition (100, 100);
	glutCreateWindow (argv[0]);
	init ();
	glutIdleFunc(idle);
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);
	//glutFullScreen();
	glutMainLoop();
	return 0;
}

// LaFolle
